package org.footballmanager.pandafootball.system.service.impl;

import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.footballmanager.pandafootball.common.annotation.SystemServiceLog;
import org.footballmanager.pandafootball.common.exception.ExceptionEnum;
import org.footballmanager.pandafootball.common.exception.MyException;
import org.footballmanager.pandafootball.common.util.RandomNumber;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 邮件发送服务类
 * 提供了一些基本的服务，如sendSimpleMail邮件记录、sendHtmlMail邮件记录等方法
 * 此类主要提供的是对发送邮件的服务，包括各种模板和简单邮件都可以使用此类
 *
 * @author chenjian
 * @since 2017年9月27日上午10:57:28
 */
@Service
public class EmailSenderService {
	@Autowired
	private JavaMailSender mailSender; //自动注入的Bean

	@Autowired
	private FreeMarkerConfigurer freeMarkerConfigurer;  //自动注入

	@Value("${emailsender}")
	private String sender;

	/**
	 * sendSimpleMail邮件记录
	 * @param reciver 参数
	 * @param title 参数
	 * @param text 参数
	 */
	@SystemServiceLog(description = "sendSimpleMail邮件记录")
	public void sendSimpleMail(String reciver, String title, String text){
		SimpleMailMessage message = new SimpleMailMessage();
		message.setFrom(sender);
		message.setTo(reciver); //自己给自己发送邮件
		message.setSubject(title);
		message.setText(text);
		mailSender.send(message);
	}

	/**
	 * sendHtmlMail邮件记录
	 * @param reciver 参数
	 * @param title 参数
	 * @param sb 参数
	 */
	@SystemServiceLog(description = "sendHtmlMail邮件记录")
	public void sendHtmlMail(String reciver, String title, StringBuilder sb){
		try {
			MimeMessage message = mailSender.createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(message, true);
			helper.setFrom(sender);
			helper.setTo(reciver);
			helper.setSubject(title);
			helper.setText(sb.toString(), true);
			mailSender.send(message);
		} catch (MessagingException e) {
			throw new MyException(ExceptionEnum.SENDEMAILEXCEPTION, e);
		}
	}

	/**
	 * sendInlineMail邮件记录
	 * @param reciver 参数
	 * @param title 参数
	 * @param contentHtml 参数
	 * @param file 参数
	 * @param filename 参数
	 */
	@SystemServiceLog(description = "sendInlineMail邮件记录")
	public void sendInlineMail(String reciver, String title, String contentHtml, File file, String filename){
		try{
			MimeMessage message = mailSender.createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(message, true);
			helper.setFrom(sender);
			helper.setTo(reciver);
			helper.setSubject(title);
			//第二个参数指定发送的是HTML格式,同时cid:是固定的写法
			helper.setText(contentHtml, true);

			FileSystemResource fsr = new FileSystemResource(file);
			helper.addInline(filename, fsr);
			mailSender.send(message);
		} catch (MessagingException e) {
			throw new MyException(ExceptionEnum.SENDEMAILEXCEPTION, e);
		}
	}

	/**
	 * sendAttachmentsMail邮件记录
	 * @param reciver 参数
	 * @param title 参数
	 * @param content 参数
	 * @param file 参数
	 * @param filename 参数
	 */
	@SystemServiceLog(description = "sendAttachmentsMail邮件记录")
	public void sendAttachmentsMail(String reciver, String title, String content, File file, String filename){
		try{
			MimeMessage message = mailSender.createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(message, true);
			helper.setFrom(sender);
			helper.setTo(reciver);
			helper.setSubject(title);
			helper.setText(content);
			//注意项目路径问题，自动补用项目路径
			FileSystemResource fsr = new FileSystemResource(file);
			//加入邮件
			helper.addAttachment(filename, fsr);
			mailSender.send(message);
		} catch (MessagingException e) {
			throw new MyException(ExceptionEnum.SENDEMAILEXCEPTION, e);
		}
	}

	/**
	 * sendTemplateMail邮件记录
	 * @param reciver 参数
	 * @param title 参数
	 * @param param 参数
	 * @param filename 参数
	 */
	@SystemServiceLog(description = "sendTemplateMail邮件记录")
	public void sendTemplateMail(String reciver, String title, Map<String, Object> param, String filename){
		try{
			MimeMessage message = mailSender.createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(message, true);
			helper.setFrom(sender);
			helper.setTo(reciver);
			helper.setSubject(title);
			//读取 html 模板
			Template template = freeMarkerConfigurer.getConfiguration().getTemplate(filename);
			Map<String, Object> newParam = getNewMap(param);
			String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, newParam);
			helper.setText(html, true);
			mailSender.send(message);
		} catch (MessagingException e) {
			throw new MyException(ExceptionEnum.SENDEMAILEXCEPTION, e);
		} catch (IOException e) {
			throw new MyException(ExceptionEnum.NOEMAILMODELEXCEPTION, e);
		} catch (TemplateException e) {
			throw new MyException(ExceptionEnum.PROCESSMODELEXCEPTION, e);
		}
	}

	/**
	 * 获取新Map
	 * @param map 参数
	 * @return 返回值
	 */
	private Map<String, Object> getNewMap(Map<String, Object> map){
		for(Map.Entry<String, Object> entry : map.entrySet()){
			if(entry.getValue() == null){
				entry.setValue("");
			}
		}
		return map;
	}

	/**
	 *  发送重置密码邮件
	 * @param username 用户名
	 * @param email 电子邮箱
	 * @param index 索引
	 * @param image 图片名称
	 * @return 重新生成邮箱失效时间
	 */
	@SystemServiceLog(description = "sendResetPasswordEmail邮件记录")
	public Map<String, Object> sendResetPasswordEmail(String username, String email, String index, String image){
		String title = "房屋管理系统重置密码，请查收";
		String template = "resetpwd.ftl";
		
		Map<String, Object> param = new HashMap<>();
		param.put("username", StringUtils.isEmpty(username) ? email : username);
		param.put("index", index);
		param.put("title_image", image);
		String forgetPwdCode = RandomNumber.randomStrByNum(6);
		param.put("content",forgetPwdCode);
		
		Map<String, Object> result = new HashMap<>();
		result.put("forgetPwdCode", forgetPwdCode);
		result.put("verificationCodeTime", System.currentTimeMillis() / 1000 + Long.parseLong("3600"));
		
		this.sendTemplateMail(email, title, param, template);
		return result;
	}
	
	/**
	 * 发送注册验证邮件
	 * @param username 用户名
	 * @param email 电子邮箱
	 * @param basePath 模板路径
	 * @param image 图像名称
	 */
	@SystemServiceLog(description = "sendRegistEmail邮件记录")
	public void sendRegistEmail(Long id, String username, String email, String basePath, String image){
		String title = "房屋管理系统激活账号身份验证";
		String template = "regist.ftl";
		
		Map<String, Object> param = new HashMap<>();
		param.put("username", StringUtils.isEmpty(username) ? email : username);
		param.put("title_image", image);
		String url = basePath + "/emailActivate?userId=" + id + "&email=" + email;
		param.put("url",url);
		
		this.sendTemplateMail(email, title, param, template);
	}
}
